# -*- coding: utf-8 -*-

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtNetwork import *

from modules import config
from modules import service

import os
import time

import urllib2
import urllib
import socket

socket.setdefaulttimeout(15)

class Download(QObject):
	def __init__(self, url, parent = None ):
		QObject.__init__(self, parent)
		self.parent = parent
		
		self.tree = parent.ui.download
		
		url = url
		
		serv = service.getObj( url )
		
		path = config.loadConf('download_path')
		filename = unicode( serv.getFileName(), "utf-8" )
		filepath = os.path.join( path, filename )

		if os.access( path, os.W_OK ):
			if os.path.lexists( filepath ):
				if os.path.isdir( filepath ):
					msg = QMessageBox( self.parent )
					msg.setText( self.tr("A folder named %1 already exists. Please, choose other folder.").arg(filename) )
					msg.setWindowTitle( self.tr("Error!") )
					msg.setIcon( QMessageBox.Critical )
					msg.exec_()

					path = self.parent.config.saveTo( False )
					filepath = os.path.join( path, filename)
				else:
					msg = QMessageBox( self.parent )
					msg.setText( self.tr("A file named %1 already exists. Are you sure you want to overwrite it?").arg(filename) )
					msg.setWindowTitle( self.tr("File exists!") )
					msg.setIcon( QMessageBox.Question )
					nob = msg.addButton( self.tr("No"), QMessageBox.ActionRole )
					ovb = msg.addButton( self.tr("Overwrite"), QMessageBox.ActionRole )
					msg.exec_()
					if msg.clickedButton() == nob:
						path = self.parent.config.saveTo( False )
						filepath = os.path.join( path, filename)
		else:
			msg = QMessageBox( self.parent )
			msg.setText( self.tr("You don't have permissions in order to download the file in specified path. Please, choose other one.") )
			msg.setWindowTitle( self.tr("Error!") )
			msg.setIcon( QMessageBox.Critical )
			msg.exec_()

			path = self.parent.config.saveTo( False )
			filepath = os.path.join( path, filename)

		self.item = QTreeWidgetItem( self.tree )
		self.item.setSizeHint(0, QSize(0, 20) )
		self.progressBar = QProgressBar()
		self.progressBar.setMaximumHeight(20)
		self.progressBar.setMinimumHeight(20)
		self.tree.setItemWidget( self.item, 2, self.progressBar )
		self.tree.resizeColumnToContents(1)

		self.tree.show()

		self.updateInfo( 0, QString( filename ) )
		self.updateInfo( 3, QString( "Waiting..." ) )
		self.updateProgressBar( 0, 100 )

		self.thread = downloadThread( self.item, [serv, path, filename, filepath], self )
		self.connect( self.thread, SIGNAL("updateInfo"), self.updateInfo )
		self.connect( self.thread, SIGNAL("updateColor"), self.updateColor )
		self.connect( self.thread, SIGNAL("updateProgressBar"), self.updateProgressBar )
		self.connect( self.thread, SIGNAL("sendTip"), self.doTip )
		self.thread.start()
		
	def kill(self):
		self.thread.skip = True
		
		self.tree.takeTopLevelItem( self.tree.indexOfTopLevelItem( self.item ) )
			
	def updateInfo(self, column, text):
		self.item.setText( column, text )
		
	def updateColor(self, color):
		self.item.setTextColor( 0, QColor(color) )

	def updateProgressBar(self, value, max):
		self.progressBar.setMaximum( max )
		self.progressBar.setValue( value )
			
	def doTip(self, text):
		self.parent.parent.tray.showMessage( self.tr('Download'), text )
			
class downloadThread(QThread):
	def __init__(self, item, info, parent):
		QThread.__init__( self, parent )
		self.parent = parent
		self.item = item
		self.info = info
		
		self.skip = False
		self.ttime = 0
		self.dwld = 0
		self.rate = 1
		self.left = 0
		
	def run(self):
		serv = self.info[0]
		
		while 1:
			if self.parent.parent.isDownloading == False:
				break
			time.sleep( 1 )
				
		self.parent.parent.isDownloading = self.parent.item
		
		while 1:
			url = serv.getUrl()
			if url == 'wait':
				if config.loadConf('show_messages') == 'yes':
					self.sendTip( self.tr('Waiting %1 minute(s) on limits period').arg(str( serv.getSleepTime() / 60 )))
				self.sleep( serv.getSleepTime() )
			else:
				break
		
		if config.loadConf('show_messages') == 'yes' and serv.getSleepTime():
			self.sendTip(self.tr('Waiting %1 second(s) to download').arg(str( serv.getSleepTime() )) )
		
		self.sleep( serv.getSleepTime() )
		
		self.updateInfo( 3, QString('') )
		
		if config.loadConf('show_messages') == 'yes':
			self.sendTip( self.tr('Started downloading %1').arg(self.info[2]) )
			
		self.updateColor('orange')
		
		dwld = 0
		i = 0
		
		req = urllib2.Request(url)
		
		if not service.CookieStore.get( serv.type() ) == False:
			req.add_header("Cookie", service.CookieStore.get( serv.type() ))
			req.add_header("User-Agent", "Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.6) Gecko/20061201 Firefox/2.0.0.8 (Ubuntu-gutsy)")
		
		try:
			tout = urllib2.urlopen( req )
		except:
			self.parent.parent.isDownloading = False;
		
			self.updateColor('red')
			
			if config.loadConf('show_messages') == 'yes':
				self.sendTip( self.tr('%1 timeout.').arg(self.info[2]) )
			self.emit(SIGNAL("updateProgressBar"), 0, 1)
			return False
		
		headers = tout.info()
		size = int( headers['Content-Length'] )

		tin = open( self.info[3], 'wb' )

		while dwld < size:
			if self.skip == True:
				break

			tin.write( tout.read( 4096 ) )
			dwld = dwld + 4096
			self.hook(dwld, size)
		tin.close()
		tout.close()
		
		self.parent.parent.isDownloading = False;
		
		self.updateColor('green')
			
		if config.loadConf('show_messages') == 'yes' and self.skip == False:
			self.sendTip( self.tr('%1 done.').arg(self.info[2]) )

		self.updateInfo(1, self.tr("%1 MiB").arg( str( round( float( size ) / 1024 / 1024 ,2) ) ) )
		self.emit(SIGNAL("updateProgressBar"), 100, 100)
		self.updateInfo(3, self.tr("") )
		self.updateInfo(4, self.tr("") )
		
	def updateColor(self, color):
		self.emit(SIGNAL("updateColor"), color)
		
	def updateInfo(self, column, text):
		self.emit(SIGNAL("updateInfo"),  column, text)

	def sendTip(self, text):
		self.emit(SIGNAL("sendTip"),  text)
						
	def sleep(self, t):
		while t > 0:
			t -= 1
			self.updateInfo( 3, self.tr( '%1 to download' ).arg( str(t) ) )
			time.sleep(1)
			
	def hook(self, downloaded, totalsize):
		timed=time.time()

		if timed - self.ttime >= 1:

			self.emit(SIGNAL("updateProgressBar"), downloaded, totalsize)

			downloaded_mib=str(round(float(downloaded)/1024/1024,2))
			totalsize_mib=str(round(float(totalsize)/1024/1024 ,2))
			self.updateInfo(1, self.tr("%1 / %2 MiB").arg(downloaded_mib, totalsize_mib))


			rate=float(downloaded-self.dwld)/(timed-self.ttime)

			if self.rate > 0:
				if rate/self.rate > 0.95 and rate/self.rate < 1.05:
					rate_kib=str(int(round((rate+self.rate)/2/1024)))
					self.updateInfo(3, self.tr("%1 KiB/s").arg(rate_kib))
					left=int(round((totalsize-downloaded)/rate))
				else:
					left=self.left-1

					if left < 61:
						strleft=self.tr("%1 s left").arg(left)
					else:
						minutes=int(round(left/60))
						seconds=left-(minutes*60)
						strleft=self.tr("%1 min %2 s left").arg(str(minutes), str(seconds))

					if left > 0:
						self.updateInfo(4, strleft)

					self.left=left


			self.dwld=downloaded
			self.ttime=timed
			self.rate=rate

			return True
